package com.suduku.handle;

import com.suduku.entity.Box;
import com.suduku.entity.Sudo;
import com.suduku.calc.enums.CalcEnum;
import com.suduku.listener.SudoListener;
import com.suduku.calc.register.SudoCalcRegister;
import com.suduku.util.SudoUtil;

import java.util.List;

/**
 * 数独处理者 <br/>
 *
 * @author chena
 */
public class SudoHandler {

    /** 数独数据 */
    private final Sudo sudo;
    /** 统计次数 */
    private int count;
    /** 监听 */
    private final SudoListener listener;

    public SudoHandler(String str) {
        this(str, null);
    }

    public SudoHandler(String str, SudoListener listener) {
        // 校验 str 是否满足数独
        SudoUtil.isSudoCheck(str);
        // 转换成 List<Box>
        List<Box> boxList = SudoUtil.toBoxList(str);
        // 创建 Sudo
        this.sudo = new Sudo(boxList, listener);
        this.listener = this.sudo.getListener();
        // 注册算法
        SudoCalcRegister.register(sudo);
    }

    /**
     * 开始推算 <br/>
     */
    public void calculate() {
        // 从注册表中，获取解题方法，一个一个尝试，如果其中一个有改变值，则从头开始继续尝试。
        boolean isChange = false;
        for(CalcEnum ce : CalcEnum.values()) {
            isChange = SudoCalcRegister.get(ce).calculate();
            count++;
            if(isChange) {
                break;
            }
        }
        if(isChange) {
            if(!this.sudo.isFinish()) {
                // 重复执行
                calculate();
            } else {
                // 解题完成
                this.listener.sendMsg("============数独解题完成，尝试次数为:%d============", count);
            }
        } else {
            // 无解
            this.listener.sendMsg("************************数独解题失败，一共尝试了：%d次************************", count);
        }
    }

}
